#include <dlfcn.h>
#include <execinfo.h>
#include <signal.h>
#include <unistd.h>

#include "LogControl.h"
#include "SingleApplication.h"
#include "DataCommon.h"
#include "BasicInfoModule.h"


void trappingSignals(void);
static void crashHandler(int sig);
void loadLogFeature(const QString &strAppName);

int main(int argc, char *argv[])
{
    bool oneShot(false);
    for (int32_t index = 0; index < argc; index++)
    {
        QString tempStr(argv[index]);
        if(tempStr == "--timer")
        {
            oneShot = true;
        }
    }
    //  设置环境变量
    setenv("LANGUAGE","en",1);
    //  设置日志信息
    loadLogFeature(*argv);
    //  设置退出信号函数
    // trappingSignals();
    SingleApplication application(argc, argv);
    if(!application.isRunningFunction())
    {
        DataCommon dataCommon;
        return application.exec();
    }
//    if (!application.isRunningFunction()) {
//        if (oneShot) {
//            DeviceInfoControl DeviceInfoControl;
//            if(LogControl::status() == LogControl::Run)
//            {
//                LogControl::exit();
//            }
//            return 0;
//        } else {
//            qDebug() << "enter dataCollection";
//            DeviceInfoThread::init();
//            DataCollection dataCollection;
//            return application.exec();
//        }
//    }
    sleep(1);
    return 0;
}

void loadLogFeature(const QString &strAppName)
{
    const QString log4QtLibName("/usr/lib/libukui-log4qt.so");
    const QString log4QtFuncName("initUkuiLog4qt");
    void *dlFd = nullptr;
    void *funcPoint = nullptr;
    auto (*ukuiLog4QtFuncPoint)(const char *)->int = nullptr;
    int ret;
    dlFd = dlopen(log4QtLibName.toUtf8(), RTLD_LAZY);
    if (dlFd == nullptr) {
        LogControl::init(strAppName);
        return;
    }
    ukuiLog4QtFuncPoint = reinterpret_cast<int (*)(const char *)>(dlsym(dlFd, "initUkuiLog4qt"));
    if (ukuiLog4QtFuncPoint == nullptr) {
        dlclose(dlFd);
        LogControl::init(strAppName);
        return;
    }
    ret = (*ukuiLog4QtFuncPoint)(strAppName.toStdString().c_str());
    if (ret < 0) {
        dlclose(dlFd);
        LogControl::init(strAppName);
        return;
    }
}

static void crashHandler(int sig)
{
    int32_t buffSize = 1024;
    signal(sig, SIG_IGN);
    size_t size = 0;
    char **strings = NULL;
    size_t i = 0, j = 0;
    void *array[20];
    size = backtrace(array, 20);
    strings = const_cast<char **> (backtrace_symbols(array, size));
    qCritical().noquote() << QString("!!!--- %1 received signal: %2=%3 ---!!!")
        .arg(QDateTime::currentDateTime().toString(
            "yyyy-MM-dd hh:mm:ss.zzz"))
        .arg(sig)
        .arg(strsignal(sig))
        .toUtf8();
    QString trackLog;
    for (i = 0; i < size; i++) {
        trackLog.append(QString("%1 %2\n").arg(i).arg(strings[i]));
    }
    qCritical().noquote() << trackLog.toUtf8();
    free(strings);
    exit(128 + sig);
}

void trappingSignals(void)
{
    if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) //忽略子进程已经停止或退出
    {
        //注册SIGCHLD信号失败
        perror("signal error");
    }
    if (signal(SIGSEGV, crashHandler) == SIG_ERR) //无效内存段访问
    {
        //注册SIGSEGV信号失败
        perror("signal error");
    }
    if (signal(SIGILL, crashHandler) == SIG_ERR) //非法指令
    {
        //注册SIGILL信号失败
        perror("signal error");
    }
    if (signal(SIGTERM, crashHandler) == SIG_ERR) //终止
    {
        //注册SIGTERM信号失败
        perror("signal error");
    }
    if (signal(SIGHUP, crashHandler) == SIG_ERR) //系统挂断
    {
        //注册SIGHUP信号失败
        perror("signal error");
    }
    if (signal(SIGABRT, crashHandler) == SIG_ERR) //进程停止运行
    {
        //注册SIGABRT信号失败
        perror("signal error");
    }
}
